package com.wolfcode.appointment.service.impl;

import java.util.List;

import com.wolfcode.appointment.domain.BusAppointment;
import com.wolfcode.appointment.domain.vo.BusStatementVo;
import com.wolfcode.appointment.enums.BusAppointmentEnum;
import com.wolfcode.appointment.enums.BusStatementEnum;
import com.wolfcode.appointment.enums.IsDeleteEnum;
import com.wolfcode.appointment.mapper.BusAppointmentMapper;
import com.wolfcode.appointment.service.IBusAppointmentService;
import com.wolfcode.common.core.domain.model.LoginUser;
import com.wolfcode.common.utils.DateUtils;
import com.wolfcode.common.utils.LicensePlateUtil;
import com.wolfcode.common.utils.PhoneUtil;
import com.wolfcode.common.utils.SecurityUtils;
import com.wolfcode.common.utils.spring.SpringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wolfcode.appointment.mapper.BusStatementMapper;
import com.wolfcode.appointment.domain.BusStatement;
import com.wolfcode.appointment.service.IBusStatementService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;


/**
 * 结算单Service业务层处理
 *
 * @author wolfcode
 * @date 2022-11-23
 */
@Service
public class BusStatementServiceImpl implements IBusStatementService {
    @Autowired
    private BusStatementMapper busStatementMapper;
    @Autowired
    private IBusAppointmentService appointmentService;
    @Autowired
    private BusAppointmentMapper busAppointmentMapper;

    /**
     * 查询结算单
     *
     * @param id 结算单主键
     * @return 结算单
     */
    @Override
    public BusStatement selectBusStatementById(Long id) {
        return busStatementMapper.selectBusStatementById(id);
    }

    /**
     * 查询结算单列表
     *
     * @param busStatement 结算单
     * @return 结算单
     */
    @Override
    public List<BusStatement> selectBusStatementList(BusStatement busStatement) {
        busStatement.setIsDelete(IsDeleteEnum.NO.ordinal());
        return busStatementMapper.selectBusStatementList(busStatement);
    }

    /**
     * 新增结算单
     *
     * @param busStatementVo 结算单
     * @return 结果
     */
    @Override
    public int insertBusStatement(BusStatementVo busStatementVo) {
        // 非法参数
        // 手机号
        // 车牌号码
        Assert.notNull(busStatementVo, "非法参数");
        Assert.state(PhoneUtil.isMobileNumber(busStatementVo.getCustomerPhone()),
                "手机号格式不正确");

        Assert.state(LicensePlateUtil.validate(busStatementVo.getLicensePlate()),
                "车牌号码格式不正确");
        // TODO 是否要同步到店时间到预约表中
        BusStatement busStatement = new BusStatement();
        BeanUtils.copyProperties(busStatementVo, busStatement);
        busStatement.setCreateTime(DateUtils.getNowDate());
        return busStatementMapper.insertBusStatement(busStatement);
    }

    /**
     * 修改结算单
     *
     * @param busStatementVo 结算单
     * @return 结果
     */
    @Override
    public int updateBusStatement(BusStatementVo busStatementVo) {
        Assert.notNull(busStatementVo, "非法参数");
        // 手机号验证
        Assert.state(PhoneUtil.isMobileNumber(busStatementVo.getCustomerPhone()), "手机号格式不正确");
        Assert.state(LicensePlateUtil.validate(busStatementVo.getLicensePlate()),
                "车牌号码格式不正确");
       /* Assert.state(!busStatementVo.getActualArrivalTime().before(DateUtils.getNowDate()),
                "到店时间不能在今天之前");*/
        // 只有在消费中，才能修改操作
        BusStatement busStatement = busStatementMapper.selectBusStatementById(busStatementVo.getId());
        Assert.notNull(busStatement, "该结算单不存在");
        boolean isConsuming = busStatement.getStatus() == BusStatementEnum.CONSUMING.ordinal();
        Assert.state(isConsuming, "只有结算状态在消费中，才能修改操作");

        BusStatement statement = new BusStatement();
        BeanUtils.copyProperties(busStatementVo, statement);
        return busStatementMapper.updateBusStatement(statement);
    }

    /**
     * 逻辑删除
     *
     * @param ids 结算单主键
     * @return
     */
    @Override
    public int logicDeleteStatement(Long ids) {
        Assert.notNull(ids, "非法参数");

        BusStatement busStatement = busStatementMapper.selectBusStatementById(ids);
        Assert.notNull(busStatement, "结算单不存在");
        boolean isConsuming = busStatement.getStatus() == BusStatementEnum.CONSUMING.ordinal();
        Assert.state(isConsuming, "只有结算状态在消费中，才能删除操作");
        BusStatement statement = new BusStatement();
        statement.setId(ids);
        // 代表逻辑删除
        statement.setIsDelete(IsDeleteEnum.YES.ordinal());
        return busStatementMapper.updateBusStatement(statement);
    }

    /**
     * 生成结算单
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public BusStatement generateStatement(Long id) {
        Assert.notNull(id, "非法参数");
        BusAppointment busAppointment = busAppointmentMapper.selectBusAppointmentById(id);
        // 已到店，才能生成结算单
        // 已结算，已支付
        Assert.state(busAppointment.getStatus() == BusAppointmentEnum.ARRIVAL.ordinal()
                        || busAppointment.getStatus() == BusAppointmentEnum.STATEMENT.ordinal()
                        || busAppointment.getStatus() == BusAppointmentEnum.PAYED.ordinal()
                , "该状态不能生成结算单");
        // 通过预约id，查询结算单
        // 假如结算单存在，直接返回
        // 结算单假如不存在，才要生成
        BusStatement statement = busStatementMapper.selectBusStatementByAppointmentId(id);
        if (statement != null) {
            // 使用合理的判断更简单
            // 检测状态
            //我期望它不是(结算单已支付，预约单已到店)
            Assert.state(!(statement.getStatus()==BusStatementEnum.PAYED.ordinal()
                            && busAppointment.getStatus()==BusAppointmentEnum.ARRIVAL.ordinal()),
                    "预约状态和结算单支付状态不一致");
            //我期望它不是(结算单已支付，预约单已结算)
            Assert.state(!(statement.getStatus()==BusStatementEnum.PAYED.ordinal()
                            && busAppointment.getStatus()==BusAppointmentEnum.STATEMENT.ordinal()),
                    "预约状态和结算单支付状态不一致");
            return statement;
        }
        // 落库
        // 结算单表
        BusStatement busStatement = new BusStatement();
        BeanUtils.copyProperties(busAppointment, busStatement);
        busStatement.setId(null);
        busStatement.setStatus(BusStatementEnum.CONSUMING.ordinal());
        busStatement.setAppointmentId(id);
        busStatementMapper.insertBusStatement(busStatement);
        // 更新预约表信息
        BusAppointment updateAppointment = new BusAppointment();
        updateAppointment.setId(id);
        updateAppointment.setStatus(BusAppointmentEnum.STATEMENT.ordinal());
        busAppointmentMapper.updateBusAppointment(updateAppointment);
        return busStatement;
    }

    /**
     * 支付
     *
     * @param id
     */
    @Override
    @Transactional
    public void pay(Long id) {
        Assert.notNull(id, "非法参数");
        // 查询结算单
        // 消费中的状态才可以支付
        BusStatement busStatement = busStatementMapper.selectBusStatementById(id);
        Assert.state(busStatement.getStatus()
                == BusStatementEnum.CONSUMING.ordinal(), "消费中的状态才可以支付");
        // 修改结算单的消费状态
        LoginUser loginUser = SecurityUtils.getLoginUser();
        // 改成已支付
        BusStatement updateStatement = new BusStatement();
        updateStatement.setId(id);
        updateStatement.setStatus(BusStatementEnum.PAYED.ordinal());
        // 支付时间
        updateStatement.setPayTime(DateUtils.getNowDate());
        // 收款人
        updateStatement.setPayeeId(loginUser.getUserId());
        busStatementMapper.updateBusStatement(updateStatement);
        // 预约客户
        Long appointmentId = busStatement.getAppointmentId();
        if (appointmentId != null) {
            // 结算单 --- 预约类型，非预约类型 --- 有咩有appointmentId
            // 修改预约状态
            BusAppointment updateAppointment = new BusAppointment();
            updateAppointment.setId(appointmentId);
            updateAppointment.setStatus(BusAppointmentEnum.PAYED.ordinal());
            busAppointmentMapper.updateBusAppointment(updateAppointment);
        }

    }

//    /**
//     * 批量删除结算单
//     *
//     * @param ids 需要删除的结算单主键
//     * @return 结果
//     */
//    @Override
//    public int deleteBusStatementByIds(Long[] ids)
//    {
//        return busStatementMapper.deleteBusStatementByIds(ids);
//    }

//    /**
//     * 删除结算单信息
//     *
//     * @param id 结算单主键
//     * @return 结果
//     */
//    @Override
//    public int deleteBusStatementById(Long id)
//    {
//        return busStatementMapper.deleteBusStatementById(id);
//    }


}
